package com.ganbo.stock.service.impl;


import com.ganbo.stock.dto.FundStockLastDTO;
import com.ganbo.stock.enums.ServiceType;
import com.ganbo.stock.utils.ThreadUtils;
import com.ganbo.stock.config.DingDingConfig;
import com.ganbo.stock.config.Ig507Config;
import com.ganbo.stock.dto.StockRealDTO;
import com.ganbo.stock.entity.FundStock;
import com.ganbo.stock.entity.FundStockBlackList;
import com.ganbo.stock.entity.FundStockLast;
import com.ganbo.stock.entity.FundStockLastHistory;
import com.ganbo.stock.repository.FundStockBlackListRepository;
import com.ganbo.stock.repository.FundStockLastHistoryRepository;
import com.ganbo.stock.repository.FundStockLastRepository;
import com.ganbo.stock.repository.FundStockRepository;
import com.ganbo.stock.service.FundStockLastService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class FundStockLastServiceImpl extends BaseService implements FundStockLastService {

    @Autowired
    FundStockLastRepository fundStockLastRepository;
    @Autowired
    FundStockRepository fundStockRepository;
    @Autowired
    DingDingGroupMessageService dingDingGroupMessageService;
    @Autowired
    DingDingConfig dingDingConfig;
    @Autowired
    Ig507Config ig507Config;
    @Autowired
    FundServiceImpl fundServiceImpl;
    @Autowired
    FundStockLastHistoryRepository fundStockLastHistoryRepository;
    @Autowired
    FundStockBlackListRepository fundStockBlackListRepository;
    @Autowired
    FundStockLastService fundStockLastService;

    @Transactional
    public void initFundStockLast() {
        log.info("===================>开始生成基金持仓最多的股票<==================");
        List<FundStockLastDTO> fundStocks = fundStockRepository.findFundStockLast();
        if (CollectionUtils.isEmpty(fundStocks)) return;
        fundStocks.sort(((o1, o2) -> Math.toIntExact(o2.getFundsNum() - o1.getFundsNum()))); //按照持仓数量多少排序

        //同一天的只保留一份统计数据
        Date now = new Date();
        List<FundStockLast> statisticsToday = fundStockLastRepository.findFundStockLastByStatistics(now);
        if (!CollectionUtils.isEmpty(statisticsToday)) fundStockLastRepository.deleteFundStockLastByStatistics(now);

        int count = 0;
        for (int i = 0; i < fundStocks.size(); i++) {
            FundStockLastDTO dto = fundStocks.get(i);
            if (dto.getFundsNum() < 4) continue; //排除加入基金持仓小于3只基金的股票

            //黑名单判断
            String stockCode = dto.getCode();
            String stockName = dto.getName();
            FundStockBlackList blackStock = fundStockBlackListRepository.findFundStockBlackListByCode(stockCode);
            if (blackStock != null) {
                log.info("生成基金持仓最多的股票：跳过黑名单股票，股票代码：{}，股票名字：{}", stockCode, stockName);
                continue;
            }

            FundStockLast last = new FundStockLast();
            last.set名字(dto.getName());
            last.set代码(stockCode);
            last.set持仓基金数量(dto.getFundsNum());
            last.set雪球个股主页(dto.getXqUrl());
            last.set当前价格(dto.getCurrentPrice());
            last.setStatistics(now);

            //持仓基金
            List<FundStock> fundStockList = fundStockRepository.findFundStockByCode(dto.getCode());
            last.set持仓基金(buildByFundNames(fundStockList));

            fundStockLastRepository.save(last);
            ++count;
        }
        log.info("===================>生成基金持仓最多的股票完毕,条数:{}<==================", (count));
    }


    @Transactional
    public void updateFundStockLastTodayReal() {
        List<FundStockLast> fundStockLasts = fundStockLastRepository.findAll();
        if (CollectionUtils.isEmpty(fundStockLasts)) return;

        Map<String, String> params = new HashMap<>();
        params.put("licence", ig507Config.getLicence());

        for (int i = 0; i < fundStockLasts.size(); i++) {
            ThreadUtils.sleepSeconds(3);
            FundStockLast fundStockLast = fundStockLasts.get(i);
            params.put("dm", fundStockLast.get代码());
            StockRealDTO stockRealDTO = sendReq(ServiceType.REAL, params, StockRealDTO.class);

            if (stockRealDTO == null) {
                log.error("Ig507拉取股票信息失败，股票代码:{},股票名字:{}", fundStockLast.get代码(), fundStockLast.get名字());
                continue;
            }

            //过滤掉PE负数的股票
            BigDecimal pe = stockRealDTO.getPe();
            if (pe != null && pe.compareTo(BigDecimal.ZERO) < 0) {
                log.info("===============过滤掉亏损的公司：name:{},pe:{}", fundStockLast.get名字(), stockRealDTO.getPe());
                fundStockLastRepository.deleteById(fundStockLast.getId());
                continue;
            }

            fundStockLastRepository.updateFundStockLastToDayReal(
                    stockRealDTO.getFm(), stockRealDTO.getH(), stockRealDTO.getHs(),
                    stockRealDTO.getLb(), stockRealDTO.getL(), stockRealDTO.getLt(),
                    stockRealDTO.getPe(), stockRealDTO.getPc(), stockRealDTO.getP(),
                    stockRealDTO.getSz(), stockRealDTO.getCje(), stockRealDTO.getUd(),
                    stockRealDTO.getV(), stockRealDTO.getVb(), stockRealDTO.getYc(),
                    stockRealDTO.getZf(), stockRealDTO.getT(), fundStockLast.getId());

            log.info("拉取股票今日盘口数据==>{}:{}/{}", fundStockLast.get名字(), (i + 1), fundStockLasts.size());
        }
    }

    //将当天生成数据备份到历史表
    @Transactional
    public void generateTodayHistory() {
        Date now = new Date();
        fundStockLastHistoryRepository.deleteFundStockLastByStatistics(now); //删除历史记录表中今天的数据
        List<FundStockLastHistory> historyList = new ArrayList<>();
        List<FundStockLast> fundStockLasts = fundStockLastRepository.findAll();
        for (FundStockLast fundStockLast : fundStockLasts) {
            FundStockLastHistory history = new FundStockLastHistory();
            BeanUtils.copyProperties(fundStockLast, history);
            historyList.add(history);
        }
        fundStockLastHistoryRepository.saveAll(historyList);
        log.info("更新当天股票池并同步到股票池历史记录表成功。。。。");
    }


    private String buildByFundNames(List<FundStock> fundStockList) {
        StringBuilder fundNames = new StringBuilder();
        for (int i = 0; i < fundStockList.size(); i++) {
            FundStock fundStock = fundStockList.get(i);
            if (i == fundStockList.size() - 1) fundNames.append(fundStock.getFundName());
            else fundNames.append(fundStock.getFundName()).append("、");
        }
        return fundNames.toString();
    }
}
